//
// Created by zj on 2022/6/27.
//

#ifndef YOYORECOGENGINE_YOYORECOGNITIONINTERFACE_H
#define YOYORECOGENGINE_YOYORECOGNITIONINTERFACE_H

#include <stdint.h>

#ifdef YOYOREG_EXPORT
#define YOYO_RECOG_API _declspec(dllexport)
#else
#define YOYO_RECOG_API
#endif

/***函数状态返回值定义***/
#define STATUS_RECOG_SUCCESS (0)           // 调用成功
#define STATUS_RECOG_ERROR (1)             // 识别库出错
#define STATUS_VALIDATION_ERROR (2)        // 加密库出错
#define STATUS_ACCELERATION_ERROR (3)      // 加速库出错
#define STATUS_PREPROCESS_ERROR (4)        // 预处理阶段出错
#define STATUS_POSTPROCESS_ERROR (5)       // 后处理阶段出错
#define STATUS_RECOG_PARA_ERROR (11)       // 传入参数错误
#define STATUS_RECOG_MEM_ERROR (12)        // 内存错误
#define STATUS_RECOG_DATA_ERROR (13)       // 数据错误
#define STATUS_RECOG_PIPILINE_ERROR (14)   // 调用流程错误
#define STATUS_RECOG_FILE_ERROR (15)       // 文件错误
#define STATUS_RECOG_KEY_EMPTY_ERROR (16)  // 键不存在错误
#define STATUS_JPEG_DATA_CORRUPTED (17)    // JPEG数据损坏

typedef void *YYRegHandle;  // 算法引擎handle类型

// 版本号类型定义
typedef struct RecogVersion {
    uint16_t Major;     // 核心功能变化,比如接口大变动, 识别模型结构的大更新
    uint16_t Minor;     // 模型类别区分
    uint16_t Revision;  // 对于同一个系列模型结构的优化迭代
    uint16_t Build;     // 构建系统自动累加, 小于4位为正式版本
    const char *Ext;    // 版本描述
    const char *Sub;    // 子版本号, 基于具体平台和场景给出
} RecogVersion;

// 模型特征类型
typedef enum RecogFeatureModeType {
    GENERAL = 0,  // 通用
    FRESH = 1,    // 生鲜
    SNACK = 2,    // 零食

    // TODO: 定制MAP
} RecogFeatureModeType;

// 平台定义
typedef enum RecogPlatformType {
    CPU = 0,
    NPU = 1,
    GPU = 2,
} RecogPlatformType;

// 引擎初始化传入参数定义
typedef struct RecogInitParam {
    char *vadCode;                  // 机器校验码
    char *workPath;                 // 识别工作目录路径
    RecogFeatureModeType featMode;  // 模型初始化特征类型
    RecogPlatformType platform;     // 运行平台指定
} RecogInitParam;

// 图像格式定义
typedef enum RecogImageType {
    RAW_RGB24 = 1,
    RAW_BGR24 = 2,
    RAW_RGBA32 = 3,
    FMT_JPEG = 100,
} RecogImageType;

// 客户端截图区域坐标（顺时针，左上 右上 右下 左下)
typedef struct RecogRegionCrop {
    uint32_t x0, y0;
    uint32_t x1, y1;
    uint32_t x2, y2;
    uint32_t x3, y3;
} RecogRegionCrop;

// 图像结构体定义
typedef struct RecogMat {
    RecogImageType format;   // 图像格式
    uint32_t width;          // 图像宽（format == FMT_JPEG 时该字段无需赋值）
    uint32_t height;         // 图像高（format == FMT_JPEG 时该字段无需赋值）
    uint32_t step;           // 图像步长（format == FMT_JPEG 时该字段无需赋值）
    RecogRegionCrop *coord;  // 截图坐标（可选）
    uint32_t dataSize;       // 图像文件流长度
    unsigned char *data;     // 图像指针
} RecogMat;

// YC类别结构体定义,YC类别输出
typedef struct RecogYcAttri {
    float score;     // YC识别绝对打分
    float refScore;  // YC的相对打分,缺省值，废弃。
    char *ycCode;    // YC编码
    char *ycName;    // YC名称
} RecogYcAttri;

// 特征信息结构体定义
typedef struct RecogFeat {
    RecogFeatureModeType featMode;  // 特征的标志
    int32_t dataSize;               // 特征长度
    float *data;                    // 特征数据的指针
} RecogFeat;

// 识别引擎输出结构体
typedef struct RecogOutput {
    int32_t magicCode;         // 模型版本代号
    int64_t recogID;           // 单次识别唯一ID
    int32_t ycAttriSize;       // YC数组的长度,最大长度为20
    RecogYcAttri *vecYcAttri;  // 输出2-YC类别相关输出,按照绝对分从高到低进行排序
    int32_t featSize;          // 特征组数目
    RecogFeat *vecFeat;        // 输出3-特征相关输出
} RecogOutput;

// 获取图像数据流的模式枚举
typedef enum RecogImageOperateType {
    INTERNAL_CACHE = 0,     // 通过内部字典KEY获取截图区域
    EXTERNAL_INCOMING = 1,  // 通过外部输入图像获取截图区域
} RecogImageOperateType;

// 图像块结构体定义
typedef struct RecogImageBlob {
    RecogImageOperateType imgMode;  // 获取图像数据流的模式
    int64_t recogID;                // 单次识别唯一ID（imgMode == INTERNAL_CACHE时，该字段需要赋值）
    RecogMat *img;                  // 图像指针（imgMode == EXTERNAL_INCOMING时，该字段需要赋值）
} RecogImageBlob;

// 图像流结构体
typedef struct RecogImageByte {
    uint32_t dataSize;    // 图像数据流长度
    unsigned char *data;  // 图像数据流指针
} RecogImageByte;

// 扩展参数编码
typedef enum RecogExpandParamType {
    DEBUG_MODE = 1,    // 开启debug模式，不需要句柄
    INFER_THREAD = 2,  // 设置推理库运行线程数，需要句柄
    FEAT_NUM = 3,      // 返回特征长度，不需要句柄
    IS_INHERIT = 4,    // 是否可兼容，需要句柄
} RecogExpandParamType;

// 可扩展接口参数
typedef struct RecogExpandParam {
    RecogExpandParamType key;  // 扩展参数编号
    void *val;                 // 参数值, void*和int互换
} RecogExpandParam;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 获取当前算法版本号
 * @return 版本号
 */
YOYO_RECOG_API RecogVersion *recogVersion();

/**
 * 识别引擎初始化
 * @param param 输入校验码以及设置平台编码
 * @return 识别引擎句柄
 */
YOYO_RECOG_API YYRegHandle recogEngineInit(const RecogInitParam *param);

/**
 * 识别引擎销毁接口
 * @param regHandle 识别引擎句柄
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogEngineUninit(YYRegHandle regHandle);

/**
 * 识别引擎识别主接口
 * @param regHandle 识别引擎句柄
 * @param imgIn 输入结构体指针
 * @param recogOut 识别输出,注意：内存由算法内部管理
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogProcess(YYRegHandle regHandle, RecogMat *imgIn, RecogOutput *recogOut);

/**
 * 识别主功能获取图像回调接口
 * 注意：内部缓存的图像队列有大小限制，会定时清空，所以外部调用过程中需要同步进行处理
 * @param RecogImageBlob 待处理图像块指针，需要指定模式
 * @param RecogImageByte 图像数据流,内存由算法内部管理
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogGetImage(RecogImageBlob *imgBlobIn, RecogImageByte *imgByteOut);

/**
 * 识别主功能获取图像回调接口,需要和getImageByteFromBlob配套使用
 * @param RecogImageBlob 待处理图像块指针，需要指定模式
 * @param RecogImageByte 图像数据流
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogFreeImage(RecogImageBlob *imgBlobIn, RecogImageByte *imgByteOut);

/**
 * 可扩展接口参数设置
 * @param regHandle 句柄, 设置debug开关时需要使用
 * @param RecogExpandParam 输入配置参数
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogSetParam(YYRegHandle regHandle, RecogExpandParam *recogParam);

/**
 * 可扩展接口获取对应输出值
 * @param regHandle 句柄, 获取debug开关时需要使用
 * @param RecogExpandParam 获取输出值
 * @return 状态返回值
 */
YOYO_RECOG_API int32_t recogGetParam(YYRegHandle regHandle, RecogExpandParam *recogParam);

#ifdef __cplusplus
}
#endif

#endif  // YOYORECOGENGINE_YOYORECOGNITIONINTERFACE_H
